package com.sakiko.ioc_03;

import com.sakiko.ioc_03.UserDao;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    /**
     * <property name="userDao" ref="userDao"
     *
     * @Autowired 作用: 给引用类型属性设置对象
     * @Autowired 原理: 根据变量类型，在 ioc容器中查询组件，如果类型唯一，直接装配;
     * 如果类型不唯一，使用变量名称作为 id值去尝试匹配 如果都没有，直接抛出异常
     * @Autowired 错误:
     * 1、没有 userDao: NoSuchBeanDefinitionException
     * 2、有多个类型且名称还不对应: NoUniqueBeanDefinitionException
     * <p>
     * 拓展 1: 佛系装配 默认 boolean required() default true;
     * 拓展 2: 类型有多个组件选择问题 1、变量名 【改】 = 组件名 【改】 2、@Qualifier(value = "userDaoImpl2") 【多个且不匹配，帮助 @Autowired做选择】 这个注解优先判定谁有资格
     * 拓展 3: @Resource (JSR-250 java提供) = @Autowired + @Qualifier (spring提供)
     */
//    @Qualifier(value = "userDaoImpl2") // note: 当然，如果使用了 @Qualifier 只要这个 value属性值唯一，也不会出现 NoUniqueBeanDefinitionException
//    @Autowired()

//    @Autowired(required = false)
    @Resource(name = "userDaoImpl2")
    private UserDao userDao1; // 看上面注解 和 UserDaoImpl1 就能理解
    // 因为本质是 给 name = "属性名" 赋值 ref = "ioc的符合 UserDao的实例类"，
    // 然后因为实例类重复时，对 name赋值会用【使用变量名称作为 id值去尝试匹配】的方法
    // @Repository 注入 id = "" (默认是类名首字母小写，可以改成 value属性的值)
    // 所以 变量名 【改】 = 组件名 【改】这个可以解决冲突
    // note: 一般使用类不会重复，直接使用注入的类(首字母小写)作为变量，就不会出现 NoUniqueBeanDefinitionException冲突问题
    //  eg: 这里将 userDao1 改成 userDaoImpl 就可以把 UserDaoImpl中 @Repository注解的 value属性值去掉，省去这些琐碎步骤

    public void find() {
        userDao1.query();
    }
}
